<template>
    <view class="container">
        选择图片生成水印后上传
        <u-upload
            :fileList="fileList1"
            @afterRead="afterRead"
            @delete="deletePic"
            name="1"
            multiple
            :maxCount="10"
        ></u-upload>
        <!-- 使用组件 -->
        <DrawImage
            :fileList="fileList1"
            :handleUploadFile="handleUploadFile"
            @handleSetAttr="handleSetAttr"
            @handleSplice="handleSplice"
        ></DrawImage>
        <button @click="onClick">获取图片列表</button>

        <!-- 不使用组件 -->
        <!-- <div class="canvas-box">
            <img
                v-for="(item, index) in fileList1"
                :key="index"
                :src="item.url"
                @load="(e) => onImageLoad(e, item)"
                @error="onImageError"
            />
            <canvas
                id="myCanvas"
                canvas-id="myCanvas"
                :style="{
                    width: `${canvasWidth}px`,
                    height: `${canvasHeight}px`,
                }"
            ></canvas>
        </div> -->
    </view>
</template>

<script>
import {
    timeFormat,
    handleCompressImage,
    randomString,
} from '@/utils/index.js';
import DrawImage from './DrawImage.vue';
export default {
    components: {
        DrawImage,
    },
    data() {
        return {
            tempImgUrl: '',
            fileList1: [],
            tempImgList: [],
            imageUrl: '../../static/cat.jpg',
            canvasWidth: 300,
            canvasHeight: 150,
            imgHeight: 500, //默认高度，用于计算比例
            watermarkText: [
                '部门：A部门',
                '电话：18398984565',
                '提交人：张三',
                // '提交时间：2025-03-14 21:10:00',
            ],
            prefix: 'http://192.168.1.9:9999/file/access/images',
        };
    },
    methods: {
        onClick() {
            console.log(this.fileList1);
        },
        // 统一添加水印并上传
        async handleUpload() {
            for (let i = 0; i < this.fileList1.length; i++) {
                const item = this.fileList1[i];
                if (item.status === 'success') continue;
                try {
                    const src = await this.uploadFilePromise(
                        item.url,
                        item.textList,
                        item.originWidth,
                        item.originHeight
                    );
                    this.fileList1.splice(
                        i,
                        1,
                        Object.assign(item, {
                            status: 'success',
                            url: `${this.prefix}/${src}`,
                        })
                    );
                } catch (error) {
                    console.error(error);
                }
            }
        },
        // 图片加载完成
        onImageLoad(event, item) {
            if (item.status === 'success') return; //上传过就不再执行
            const { width, height } = event.target; // 获取宽度和高度

            const i = this.fileList1.findIndex((x) => x.id === item.id);
            this.fileList1[i].originWidth = width; //图片真是宽度
            this.fileList1[i].originHeight = height; //图片真实高度
            this.fileList1[i].drawStatus = 'done'; //图片加载完成

            const allDone = this.fileList1.every(
                (x) => x.drawStatus === 'done'
            );
            // 全部加载完了再统一绘制canvas并上传
            if (allDone) {
                this.handleUpload();
            }
        },
        // 图片加载失败
        onImageError(err) {
            console.error('图片加载失败:', err);
        },
        // 删除图片
        deletePic(event) {
            this.fileList1.splice(event.index, 1);
        },
        // 新增图片
        async afterRead(event) {
            const textList = [...this.watermarkText];
            const time = `提交时间：${timeFormat(
                new Date(),
                'yyyy-mm-dd hh:MM:ss'
            )}`;
            textList.push(time);
            // 当设置 multiple 为 true 时, file 为数组格式，否则为对象格式
            event.file.forEach((item) => {
                this.fileList1.push({
                    id: randomString(),
                    ...item,
                    status: 'uploading',
                    drawStatus: 'todo',
                    message: '上传中',
                    textList,
                });
            });
        },
        // 添加水印
        addWatermark(option) {
            const that = this;
            const {
                watermarkText = [], // 水印文字,从下到上排列
                color = '#ff0000', // 默认字体颜色
                fontSize = 20, // 默认字体大小
                gap = 30, // 每行文字间隔 30 像素
                lastY = 80, //最下面的文字距离底部 80 像素
                x = 10, // 距离左边 10 像素
                imageUrl = '', // 图片地址
                originWidth = 0, // 原始图片宽度
                originHeight = 0, // 原始图片高度
            } = option || {};
            return new Promise(async (resolve, reject) => {
                const ctx = uni.createCanvasContext('myCanvas', that); // 'myCanvas' 是canvas的id

                const scale = originHeight / that.imgHeight; // 计算缩放比例
                const size = Math.floor(fontSize * scale); // 计算缩放后的字体大小
                that.canvasWidth = originWidth;
                that.canvasHeight = originHeight;
                ctx.drawImage(imageUrl, 0, 0, originWidth, originHeight); // 在canvas上绘制原始尺寸的图片
                ctx.fillStyle = color; // 文字颜色
                ctx.font = `${size}px Arial`; // 字体和大小
                watermarkText.forEach((text, index) => {
                    //距离底部 20 像素
                    const y = originHeight - (lastY + index * gap) * scale;
                    ctx.fillText(text, x, y); // 文字位置
                });
                ctx.draw(); // 绘制完成，显示到canvas上
                setTimeout(() => {
                    // 获取canvas图片
                    that.getImageByCanvas()
                        .then((imagePath) => {
                            resolve(imagePath);
                        })
                        .catch((err) => {
                            console.error('获取canvas图片失败:', err);
                            reject(err);
                        });
                }, 500);
            });
        },
        // 通过canvas获取图片
        getImageByCanvas() {
            const that = this;
            return new Promise((resolve, reject) => {
                // canvas转图片
                uni.canvasToTempFilePath(
                    {
                        canvasId: 'myCanvas',
                        success(res) {
                            // 获取文件信息，包括大小
                            uni.getFileInfo({
                                filePath: res.tempFilePath,
                                success: (fileInfo) => {
                                    const imgSize = fileInfo.size / 1024 / 1024; // 转换为 MB
                                    const needZip = imgSize >= 1; //大于1M就压缩
                                    if (needZip) {
                                        handleCompressImage(
                                            res.tempFilePath,
                                            10
                                        )
                                            .then((imgPath) => {
                                                resolve(imgPath);
                                            })
                                            .catch((err) => {
                                                console.error(
                                                    '压缩图片失败:',
                                                    err
                                                );
                                                reject(err);
                                            });
                                    } else {
                                        resolve(res.tempFilePath);
                                    }
                                },
                                fail: (err) => {
                                    console.error('获取文件信息失败', err);
                                },
                            });
                        },
                        fail(err) {
                            console.error('canvas转图片失败:', err);
                            reject(err);
                        },
                    },
                    that
                );
            });
        },
        handleSplice(item, data, remove) {
            const i = this.fileList1.findIndex((x) => x.id === item.id);
            if (remove) {
                this.fileList1.splice(i, 1);
                return;
            }
            this.fileList1.splice(
                i,
                1,
                Object.assign(item, {
                    status: 'success',
                    url: `${this.prefix}/${data.name}`,
                })
            );
        },
        handleSetAttr(id, width, height) {
            const i = this.fileList1.findIndex((x) => x.id === id);
            this.fileList1[i].originWidth = width; //图片真是宽度
            this.fileList1[i].originHeight = height; //图片真实高度
            this.fileList1[i].drawStatus = 'done'; //图片加载完成
        },
        // 上传图片
        handleUploadFile(filePath) {
            return new Promise((resolve, reject) => {
                uni.uploadFile({
                    url: 'http://192.168.1.9:9999/file/upload/images',
                    filePath,
                    name: 'file',
                    formData: {
                        user: 'test',
                    },
                    success: (res) => {
                        console.log('上传成功：', res);
                        const data = JSON.parse(res.data);
                        resolve(data);
                    },
                    fail: (err) => {
                        console.error('上传失败:', err);
                        reject(err);
                    },
                });
            });
        },
        uploadFilePromise(url, textList, originWidth, originHeight) {
            const that = this;
            return new Promise((resolve, reject) => {
                that.addWatermark({
                    watermarkText: textList,
                    imageUrl: url,
                    originWidth, // 原始图片宽度
                    originHeight,
                })
                    .then((filePath) => {
                        uni.uploadFile({
                            url: 'http://192.168.1.9:9999/file/upload/images',
                            filePath,
                            name: 'file',
                            formData: {
                                user: 'test',
                            },
                            success: (res) => {
                                console.log('上传成功：', res);
                                const data = JSON.parse(res.data);
                                resolve(data.name);
                            },
                            fail: (err) => {
                                console.error('上传失败:', err);
                                reject(err);
                            },
                        });
                    })
                    .catch((err) => {
                        console.error('上传失败:', err);
                        reject(err);
                    });
            });
        },
    },
};
</script>

<style lang="less" scoped>
.container {
    overflow: auto;

    .canvas-box {
        width: 0;
        height: 0;
        overflow: hidden;
    }
}
</style>
